/*
 * Copyright [2022] [https://www.xiaonuo.vip]
 *
 * Snowy采用APACHE LICENSE 2.0开源协议，您在使用过程中，需要注意以下几点：
 *
 * 1.请不要删除和修改根目录下的LICENSE文件。
 * 2.请不要删除和修改Snowy源码头部的版权声明。
 * 3.本项目代码可免费商业使用，商业使用请保留源码和相关描述文件的项目出处，作者声明等。
 * 4.分发源码时候，请注明软件出处 https://www.xiaonuo.vip
 * 5.不可二次分发开源参与同类竞品，如有想法可联系团队xiaonuobase@qq.com商议合作。
 * 6.若您的项目无法满足以上几点，需要更多功能代码，获取Snowy商业授权许可，请在官网购买授权，地址为 https://www.xiaonuo.vip
 */
package vip.xiaonuo.biz.modular.approval.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import vip.xiaonuo.auth.core.pojo.SaBaseLoginUser;
import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
import vip.xiaonuo.biz.modular.approval.entity.BizApproval;
import vip.xiaonuo.biz.modular.approval.entity.BizSummarization;
import vip.xiaonuo.biz.modular.approval.enums.BizApprovalEnum;
import vip.xiaonuo.biz.modular.approval.mapper.BizApprovalMapper;
import vip.xiaonuo.biz.modular.approval.param.*;
import vip.xiaonuo.biz.modular.approval.result.BizApprovalOrderCanteenStatisticsResult;
import vip.xiaonuo.biz.modular.approval.service.BizApprovalService;
import vip.xiaonuo.biz.modular.approval.service.BizWxService;
import vip.xiaonuo.biz.modular.approvallog.entity.BizApprovalLog;
import vip.xiaonuo.biz.modular.approvallog.service.BizApprovalLogService;
import vip.xiaonuo.biz.modular.approvalorder.entity.BizApprovalOrder;
import vip.xiaonuo.biz.modular.approvalorder.enums.BizApprovalCafeteriaTypeEnum;
import vip.xiaonuo.biz.modular.approvalorder.enums.BizApprovalPayTypeEnum;
import vip.xiaonuo.biz.modular.approvalorder.result.BizApprovalCanteenUserResult;
import vip.xiaonuo.biz.modular.approvalorder.service.BizApprovalOrderService;
import vip.xiaonuo.biz.modular.canteen.entity.BizCanteen;
import vip.xiaonuo.biz.modular.canteen.service.BizCanteenService;
import vip.xiaonuo.biz.modular.org.entity.BizOrg;
import vip.xiaonuo.biz.modular.org.service.BizOrgService;
import vip.xiaonuo.biz.modular.user.entity.BizUser;
import vip.xiaonuo.biz.modular.user.enums.BizUserRoleEnum;
import vip.xiaonuo.common.enums.CommonSortOrderEnum;
import vip.xiaonuo.common.enums.CommonSwitchEnum;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.page.CommonPageRequest;
import vip.xiaonuo.dev.api.DevSmsApi;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 审批管理Service接口实现类
 *
 * @author fqa
 * @date 2025/05/09 18:20
 **/
@Slf4j
@Service
public class BizApprovalServiceImpl extends ServiceImpl<BizApprovalMapper, BizApproval> implements BizApprovalService {
    @Autowired
    private BizCanteenService canteenService;
    @Autowired
    private BizOrgService bizOrgService;
    @Autowired
    private BizApprovalLogService bizApprovalLogService;
    @Autowired
    private BizApprovalOrderService bizApprovalOrderService;
    @Autowired
    private BizWxService bizWxService;
    @Resource
    private DevSmsApi devSmsApi;


    @Override
    public Page<BizApproval> page(BizApprovalPageParam bizApprovalPageParam) {
        QueryWrapper<BizApproval> queryWrapper = new QueryWrapper<BizApproval>().checkSqlInjection();

        if (ObjectUtil.isNotEmpty(bizApprovalPageParam.getStartVisitTime()) && ObjectUtil.isNotEmpty(bizApprovalPageParam.getEndVisitTime())) {
            queryWrapper.lambda().between(BizApproval::getVisitTime, bizApprovalPageParam.getStartVisitTime(), bizApprovalPageParam.getEndVisitTime());
        }
        if (ObjectUtil.isNotEmpty(bizApprovalPageParam.getApplicantName())) {
            queryWrapper.lambda().like(BizApproval::getApplicantName, bizApprovalPageParam.getApplicantName());
        }
        if (ObjectUtil.isNotEmpty(bizApprovalPageParam.getApplicantDeptName())) {
            queryWrapper.lambda().like(BizApproval::getApplicantDeptName, bizApprovalPageParam.getApplicantDeptName());
        }
        if (ObjectUtil.isNotEmpty(bizApprovalPageParam.getVisitDeptName())) {
            queryWrapper.lambda().like(BizApproval::getVisitDeptName, bizApprovalPageParam.getVisitDeptName());
        }
        if (ObjectUtil.isNotEmpty(bizApprovalPageParam.getVisitLunchCafeteriaName())) {
            queryWrapper.lambda().like(BizApproval::getVisitLunchCafeteriaName, bizApprovalPageParam.getVisitLunchCafeteriaName());
        }
        if (ObjectUtil.isNotEmpty(bizApprovalPageParam.getVisitSupperCafeteriaName())) {
            queryWrapper.lambda().like(BizApproval::getVisitSupperCafeteriaName, bizApprovalPageParam.getVisitSupperCafeteriaName());
        }
        if (ObjectUtil.isNotEmpty(bizApprovalPageParam.getApprovalStatus())) {
            queryWrapper.lambda().eq(BizApproval::getApprovalStatus, bizApprovalPageParam.getApprovalStatus());
        }
        if (ObjectUtil.isAllNotEmpty(bizApprovalPageParam.getSortField(), bizApprovalPageParam.getSortOrder())) {
            CommonSortOrderEnum.validate(bizApprovalPageParam.getSortOrder());
            queryWrapper.orderBy(true, bizApprovalPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
                    StrUtil.toUnderlineCase(bizApprovalPageParam.getSortField()));
        } else {
            queryWrapper.lambda().orderByDesc(BizApproval::getVisitTime);
        }

        // 校验数据范围
        List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
        if (ObjectUtil.isNotEmpty(loginUserDataScope) && !CommonSwitchEnum.isTrue(bizApprovalPageParam.getIsSelf())) {
            queryWrapper.lambda().in(BizApproval::getApplicantDeptId, loginUserDataScope);
        } else {
            queryWrapper.lambda().eq(BizApproval::getApplicantId, StpUtil.getLoginIdAsString());
        }
        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
    }

    @Override
    public Page<BizApproval> approvalPage(BizUserApprovalPageParam bizApprovalPageParam) {
        QueryWrapper<BizApproval> queryWrapper = new QueryWrapper<BizApproval>().checkSqlInjection();
        if (ObjectUtil.isNotEmpty(bizApprovalPageParam.getApprovalStatus())) {
            if (Objects.equals(bizApprovalPageParam.getApprovalStatus(), CommonSwitchEnum.TRUE.getValue())) {
                queryWrapper.lambda().in(BizApproval::getApprovalStatus, BizApprovalEnum.finishList());
            } else {
                queryWrapper.lambda().notIn(BizApproval::getApprovalStatus, BizApprovalEnum.finishList());
                queryWrapper.lambda().ne(BizApproval::getApprovalStatus, BizApprovalEnum.RECALL.getValue());
            }
        }
        queryWrapper.lambda().eq(BizApproval::getApplicantId, StpUtil.getLoginIdAsString());
        if (ObjectUtil.isAllNotEmpty(bizApprovalPageParam.getSortField(), bizApprovalPageParam.getSortOrder())) {
            CommonSortOrderEnum.validate(bizApprovalPageParam.getSortOrder());
            queryWrapper.orderBy(true, bizApprovalPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
                    StrUtil.toUnderlineCase(bizApprovalPageParam.getSortField()));
        } else {
            queryWrapper.lambda().orderByDesc(BizApproval::getVisitTime);
        }
        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
    }

    @Override
    public Page<BizApproval> disposeApprovalPage(BizDisposeApprovalPageParam bizApprovalPageParam) {
        // 校验数据范围
        List<String> roleCodeList = StpLoginUserUtil.getLoginUser().getRoleCodeList();
        if (ObjectUtil.isEmpty(roleCodeList)) {
            throw new CommonException("您没有权限进行此操作");
        }
        QueryWrapper<BizApproval> queryWrapper;
        if (roleCodeList.contains(BizUserRoleEnum.DEPT_ADMIN.getValue()) || roleCodeList.contains(BizUserRoleEnum.DEPT_ASSISTANT.getValue())) {
            queryWrapper = deptDisposeApprovalPage(bizApprovalPageParam);
        } else {
            throw new CommonException("您没有权限进行此操作");

        }
        if (ObjectUtil.isAllNotEmpty(bizApprovalPageParam.getSortField(), bizApprovalPageParam.getSortOrder())) {
            CommonSortOrderEnum.validate(bizApprovalPageParam.getSortOrder());
            queryWrapper.orderBy(true, bizApprovalPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
                    StrUtil.toUnderlineCase(bizApprovalPageParam.getSortField()));
        } else {
            queryWrapper.lambda().orderByDesc(BizApproval::getVisitTime);
        }
        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
    }

//    /**
//     * 食堂审批
//     *
//     * @param bizApprovalPageParam
//     * @return
//     */
//    public QueryWrapper<BizApproval> canteenDisposeApprovalPage(BizDisposeApprovalPageParam bizApprovalPageParam) {
//        QueryWrapper<BizApproval> queryWrapper = new QueryWrapper<BizApproval>().checkSqlInjection();
//        String canteenId = StpLoginUserUtil.getLoginUser().getCanteenId();
//
//        if (!bizApprovalPageParam.getApprovalStatus()) {
//            //待审批
//            //午餐食堂id+VISIT_DEPT or 晚餐食堂id+LUNCH_WAIT_VISIT
//            queryWrapper.and(
//                    innerWrapper -> innerWrapper.lambda().eq(BizApproval::getApprovalStatus, BizApprovalEnum.VISIT_DEPT.getValue())
//                            .eq(BizApproval::getVisitLunchCafeteriaId, canteenId)
//            ).or(
//                    innerWrapper -> innerWrapper.lambda().eq(BizApproval::getApprovalStatus, BizApprovalEnum.LUNCH_WAIT_VISIT.getValue())
//                            .eq(BizApproval::getVisitSupperCafeteriaId, canteenId)
//            );
//        } else {
//            //已审批
//            //WAIT_VISIT or VISIT_REJECT or 午餐食堂id+LUNCH_WAIT_VISIT
//            queryWrapper.and(
//                    wrapper -> wrapper.and(
//                            innerWrapper -> innerWrapper.lambda().eq(BizApproval::getApprovalStatus, BizApprovalEnum.WAIT_VISIT.getValue())
//                                    .or()
//                                    .eq(BizApproval::getApprovalStatus, BizApprovalEnum.VISIT_REJECT.getValue())
//                    ).and(
//                            innerWrapper -> innerWrapper.lambda().eq(BizApproval::getVisitLunchCafeteriaId, canteenId)
//                                    .or()
//                                    .eq(BizApproval::getVisitSupperCafeteriaId, canteenId)
//                    )
//            ).or(
//                    innerWrapper -> innerWrapper.lambda().eq(BizApproval::getVisitLunchCafeteriaId, canteenId)
//                            .eq(BizApproval::getApprovalStatus, BizApprovalEnum.LUNCH_WAIT_VISIT.getValue())
//            );
//        }
//        return queryWrapper;
//    }

    /**
     * 部门审批分页
     *
     * @param bizApprovalPageParam
     * @return
     */
    public QueryWrapper<BizApproval> deptDisposeApprovalPage(BizDisposeApprovalPageParam bizApprovalPageParam) {
        // 校验数据范围
        String orgId = StpLoginUserUtil.getLoginUser().getOrgId();
        QueryWrapper<BizApproval> queryWrapper = new QueryWrapper<BizApproval>().checkSqlInjection();
        queryWrapper.lambda().eq(BizApproval::getApplicantDeptId, orgId);
        if (bizApprovalPageParam.getApprovalStatus()) {
            //已审批
            queryWrapper.lambda().ne(BizApproval::getApprovalStatus, BizApprovalEnum.APPLICANT_DEPT.getValue());
        } else {
            //待审批
            queryWrapper.lambda().eq(BizApproval::getApprovalStatus, BizApprovalEnum.APPLICANT_DEPT.getValue());
        }
        if (ObjectUtil.isAllNotEmpty(bizApprovalPageParam.getSortField(), bizApprovalPageParam.getSortOrder())) {
            CommonSortOrderEnum.validate(bizApprovalPageParam.getSortOrder());
            queryWrapper.orderBy(true, bizApprovalPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
                    StrUtil.toUnderlineCase(bizApprovalPageParam.getSortField()));
        } else {
            queryWrapper.lambda().orderByDesc(BizApproval::getVisitTime);
        }
        return queryWrapper;
    }

    @Override
    public Page<BizApproval> waring(BizApprovalWaringParam bizApprovalPageParam) {
        QueryWrapper<BizApproval> queryWrapper = new QueryWrapper<BizApproval>().checkSqlInjection();

        if (ObjectUtil.isNotEmpty(bizApprovalPageParam.getStartVisitTime()) && ObjectUtil.isNotEmpty(bizApprovalPageParam.getEndVisitTime())) {
            queryWrapper.lambda().between(BizApproval::getVisitTime, bizApprovalPageParam.getStartVisitTime(), bizApprovalPageParam.getEndVisitTime());
        }
        if (ObjectUtil.isNotEmpty(bizApprovalPageParam.getApplicantName())) {
            queryWrapper.lambda().like(BizApproval::getApplicantName, bizApprovalPageParam.getApplicantName());
        }
        if (ObjectUtil.isNotEmpty(bizApprovalPageParam.getVisitLunchCafeteriaName())) {
            queryWrapper.lambda().like(BizApproval::getVisitLunchCafeteriaName, bizApprovalPageParam.getVisitLunchCafeteriaName());
        }
        if (ObjectUtil.isNotEmpty(bizApprovalPageParam.getVisitSupperCafeteriaName())) {
            queryWrapper.lambda().like(BizApproval::getVisitSupperCafeteriaName, bizApprovalPageParam.getVisitSupperCafeteriaName());
        }
        if (ObjectUtil.isNotEmpty(bizApprovalPageParam.getApprovalStatus())) {
            queryWrapper.lambda().eq(BizApproval::getApprovalStatus, bizApprovalPageParam.getApprovalStatus());
        }
        if (ObjectUtil.isAllNotEmpty(bizApprovalPageParam.getSortField(), bizApprovalPageParam.getSortOrder())) {
            CommonSortOrderEnum.validate(bizApprovalPageParam.getSortOrder());
            queryWrapper.orderBy(true, bizApprovalPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
                    StrUtil.toUnderlineCase(bizApprovalPageParam.getSortField()));
        } else {
            queryWrapper.lambda().orderByDesc(BizApproval::getVisitTime);
        }
        queryWrapper.lambda().apply("VISIT_PARENT_DEPT_ID=APPLICANT_PARENT_DEPT_ID");
        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(BizApprovalAddParam bizApprovalAddParam) {
        BizApproval bizApproval = BeanUtil.toBean(bizApprovalAddParam, BizApproval.class);
        this.save(bizApproval);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(BizApprovalEditParam bizApprovalEditParam) {
        BizApproval bizApproval = this.queryEntity(bizApprovalEditParam.getId());
        BeanUtil.copyProperties(bizApprovalEditParam, bizApproval);
        this.updateById(bizApproval);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<BizApprovalIdParam> bizApprovalIdParamList) {
        // 执行删除
        this.removeByIds(CollStreamUtil.toList(bizApprovalIdParamList, BizApprovalIdParam::getId));
    }

    @Override
    public BizApproval detail(BizApprovalIdParam bizApprovalIdParam) {
        return this.queryEntity(bizApprovalIdParam.getId());
    }

    @Override
    public BizApproval queryEntity(String id) {
        BizApproval bizApproval = this.getById(id);
        if (ObjectUtil.isEmpty(bizApproval)) {
            throw new CommonException("审批管理不存在，id值为：{}", id);
        }
        return bizApproval;
    }


    /**
     * 创建审批管理
     *
     * @param bizApprovalCreateParam 创建审批管理参数
     */
    @Override
    @Transactional
    public void createApproval(BizApprovalCreateParam bizApprovalCreateParam) {
        BizApproval bizApproval = BeanUtil.toBean(bizApprovalCreateParam, BizApproval.class);
        String visitLunchCafeteriaId = bizApprovalCreateParam.getVisitLunchCafeteriaId();//到访午餐食堂ID
        String visitSupperCafeteriaId = bizApprovalCreateParam.getVisitSupperCafeteriaId();//到访晚餐食堂ID
        if (ObjectUtil.isEmpty(visitLunchCafeteriaId) && ObjectUtil.isEmpty(visitSupperCafeteriaId)) {
            throw new CommonException("请选择到访食堂");
        }
        //午餐
        JSONObject lunchUserExtJsonObject = new JSONObject();
        if (ObjectUtil.isNotEmpty(visitLunchCafeteriaId)) {
            BizCanteen lunchCanteen = canteenService.queryEntity(visitLunchCafeteriaId);//到访午餐食堂
            //价格是否可修改
            if (!CommonSwitchEnum.isTrue(lunchCanteen.getCanteenPriceModifyFlag())) {
                bizApproval.setLunchPrice(lunchCanteen.getCanteenLunchPrice());
                bizApproval.setVisitLunchCafeteriaId(lunchCanteen.getId());
                bizApproval.setVisitLunchCafeteriaName(lunchCanteen.getCanteenName());
            }
            lunchUserExtJsonObject = lunchCanteen.getExtJsonObject();
        } else {
            bizApproval.setLunchPrice(BigDecimal.ZERO);
        }
        //晚餐
        JSONObject supperUserExtJsonObject = new JSONObject();
        if (ObjectUtil.isNotEmpty(visitSupperCafeteriaId)) {
            BizCanteen supperCanteen = canteenService.queryEntity(visitSupperCafeteriaId);//到访晚餐食堂
            //价格是否可修改
            if (!CommonSwitchEnum.isTrue(supperCanteen.getCanteenPriceModifyFlag())) {
                bizApproval.setSupperPrice(supperCanteen.getCanteenDinnerPrice());
                bizApproval.setVisitSupperCafeteriaId(supperCanteen.getId());
                bizApproval.setVisitSupperCafeteriaName(supperCanteen.getCanteenName());
            }
            supperUserExtJsonObject = supperCanteen.getExtJsonObject();
        } else {
            bizApproval.setSupperPrice(BigDecimal.ZERO);
        }
        //访问部门
        BizOrg visitOrg = bizOrgService.queryEntity(bizApprovalCreateParam.getVisitDeptId());
        SaBaseLoginUser loginUser = StpLoginUserUtil.getLoginUser();
        bizApproval.setApplicantId(loginUser.getId());
        bizApproval.setApplicantDeptId(loginUser.getOrgId());
        bizApproval.setApplicantName(loginUser.getName());
        bizApproval.setApplicantDeptName(loginUser.getOrgName());
        bizApproval.setApplicantDeptPhone(loginUser.getPhone());
        bizApproval.setApprovalStatus(BizApprovalEnum.APPLICANT_DEPT.getValue());
        bizApproval.setVisitDeptId(visitOrg.getId());
        bizApproval.setVisitParentDeptId(visitOrg.getParentId());
        bizApproval.setVisitDeptName(visitOrg.getName());
        bizApproval.setApplicantOpenId(loginUser.getOpenId());
        bizApproval.setApplicantParentDeptId(loginUser.getParentOrgId());
        //到访部门信息
        JSONObject visitOrgUserJson = visitOrg.getExtJsonObject();
        //申请部门信息
        JSONObject orgUserJson = bizOrgService.queryEntity(loginUser.getOrgId()).getExtJsonObject();
        JSONObject extJson = new JSONObject();
        extJson.put("visitOrgUser", visitOrgUserJson);
        extJson.put("orgUserJson", orgUserJson);
        extJson.put("lunchUser", lunchUserExtJsonObject);
        extJson.put("supperUser", supperUserExtJsonObject);
        //申请人信息
        JSONObject applicantUser = new JSONObject();
        applicantUser.put("directorName", loginUser.getName());
        applicantUser.put("directorPhone", loginUser.getPhone());
        extJson.put("applicantUser", applicantUser);
        bizApproval.setExtJson(extJson.toJSONString());
        this.save(bizApproval);
        // 发送给当前部门审批人审批
        BizUser user = bizOrgService.getOrgUserByOrgId(bizApproval.getApplicantDeptId());
        if (ObjectUtil.isEmpty(user)) {
            return;
        }
        bizWxService.sendApprovalTemplate(
                bizApproval.getApplicantDeptName(),
                bizApproval.getApplicantName(),
                DateUtil.format(bizApproval.getVisitTime(), DatePattern.NORM_DATE_PATTERN),
                "出访" + bizApproval.getVisitDeptName(),
                user.getName(),
                user.getOpenId()
        );
    }

    @Override
    @Transactional
    public void approvalOperate(BizApprovalOperateParam bizApprovalOperateParam) {
        String status = bizApprovalOperateParam.getStatus();
        BizApproval approval = this.queryEntity(bizApprovalOperateParam.getId());
        SaBaseLoginUser loginUser = StpLoginUserUtil.getLoginUser();
        List<String> roleCodeList = loginUser.getRoleCodeList();//角色

        BizApprovalEnum approvalStatus = BizApprovalEnum.WAIT_VISIT;

        if (roleCodeList.contains(BizUserRoleEnum.DEPT_ADMIN.getValue()) || roleCodeList.contains(BizUserRoleEnum.DEPT_ASSISTANT.getValue())) {
            //是部门审批人
            if (!Objects.equals(approval.getApprovalStatus(), BizApprovalEnum.APPLICANT_DEPT.getValue())) {
                throw new CommonException("您没有权限操作该审批单");
            }
        } else {
            throw new CommonException("您没有权限操作该审批单");
        }
        //
        if (!CommonSwitchEnum.isTrue(status)) {
            //审批驳回
            approvalStatus = BizApprovalEnum.VISIT_REJECT;
        }
        //
        String beforeApprovalStatus = approval.getApprovalStatus();

        //修改审批单状态
        approval.setApprovalStatus(approvalStatus.getValue());
        this.updateById(approval);

        //添加审批日志
        BizApprovalLog approvalLog = new BizApprovalLog();
        approvalLog.setApprovalId(approval.getId());
        approvalLog.setBeforeApprovalStatus(beforeApprovalStatus);
        approvalLog.setAfterApprovalStatus(approvalStatus.getValue());
        approvalLog.setApprovalUserName(loginUser.getName());
        approvalLog.setApprovalUserId(loginUser.getId());
        approvalLog.setApprovalDeptName(loginUser.getOrgName());
        approvalLog.setApprovalDeptId(loginUser.getOrgId());
        approvalLog.setRemark(bizApprovalOperateParam.getOpinion());
        approvalLog.setApprovalUserPhone(loginUser.getPhone());

        bizApprovalLogService.save(approvalLog);
        if (approvalStatus == BizApprovalEnum.WAIT_VISIT) {
            //发送食堂通知
            if (approval.getVisitLunchCafeteriaId() != null) {
                sendAppointmentTemplate(approval, approval.getVisitLunchCafeteriaId(), "请提取安排午餐");
                sendSmsAliyunTemplate(approval, approval.getVisitLunchCafeteriaId(), true);
            }
            if (approval.getVisitSupperCafeteriaId() != null) {
                sendAppointmentTemplate(approval, approval.getVisitSupperCafeteriaId(), "请提取安排晚餐");
                sendSmsAliyunTemplate(approval, approval.getVisitSupperCafeteriaId(), false);
            }
        }
    }

    @Async
    public void sendSmsAliyunTemplate(BizApproval approval, String canteenId, boolean isLunch) {
        try {
            BizCanteen canteen = canteenService.queryEntity(canteenId);
            JSONObject extJsonObject = approval.getExtJsonObject();
            JSONObject applicantUser = extJsonObject.getJSONObject("applicantUser");
            if (applicantUser == null) {
                return;
            }
            String phone = applicantUser.getString("directorPhone");
            String directorName = applicantUser.getString("directorName");
            if (ObjectUtil.isEmpty(phone)) {
                return;
            }
            String noonEvening = isLunch ? "午餐" : "晚餐";
            String templateParam = JSONUtil.toJsonStr(
                    JSONUtil.createObj()
                            .set("nameNumDept", StrUtil.format("{}-{}-{}", directorName, approval.getApplicantDeptName(), phone))
                            .set("date", DateUtil.format(approval.getVisitTime(), "MM月dd日"))
                            .set("canteen", canteen.getCanteenName())
                            .set("noonEvening", noonEvening)

            );
            JSONObject canteenJson = canteen.getExtJsonObject();
            devSmsApi.sendSmsAliyun(canteenJson.getString("directorPhone"), null, "SMS_490675345", templateParam);
        } catch (Exception e) {
            log.error("发送短信失败:{}", e.getMessage());
        }
    }

    void sendAppointmentTemplate(BizApproval approval, String canteenId, String info) {
        BizUser user = canteenService.getCanteenUserByCanteenId(canteenId);
        if (user == null || ObjectUtil.isEmpty(user)) {
            return;
        }
        bizWxService.sendAppointmentTemplate(
                approval.getApplicantName(),
                DateUtil.format(approval.getVisitTime(), DatePattern.NORM_DATETIME_MINUTE_PATTERN),
                info,
                user.getOpenId()
        );
    }


    @Override
    public BizApproval getApprovalSign(String canteenId, String cafeteriaType) {
        // 获取今天的起始时间和结束时间
        LocalDateTime startOfDay = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
        LocalDateTime endOfDay = LocalDateTime.of(LocalDate.now(), LocalTime.MAX);

        QueryWrapper<BizApproval> approvalQueryWrapper = new QueryWrapper<>();
        approvalQueryWrapper
                .lambda()
                .ge(BizApproval::getVisitTime, startOfDay) // 大于等于今天的开始时间
                .le(BizApproval::getVisitTime, endOfDay)
                .eq(BizApproval::getApprovalStatus, BizApprovalEnum.WAIT_VISIT.getValue());   // 小于等于今天的结束时间
        if (Objects.equals(cafeteriaType, BizApprovalCafeteriaTypeEnum.LUNCH.getValue())) {
            approvalQueryWrapper.lambda().eq(BizApproval::getVisitLunchCafeteriaId, canteenId);
        } else {
            approvalQueryWrapper.lambda().eq(BizApproval::getVisitSupperCafeteriaId, canteenId);
        }
        approvalQueryWrapper.lambda().eq(BizApproval::getApplicantId, StpUtil.getLoginIdAsString());
        approvalQueryWrapper.last("LIMIT 1");
        return this.getOne(approvalQueryWrapper);
    }


    @Override
    public List<BizSummarization> summarizationList() {
        return this.baseMapper.getSummarizationList();
    }

    @Override
    public void recallApproval(BizApprovalIdParam bizApprovalIdParam) {
        BizApproval approval = this.queryEntity(bizApprovalIdParam.getId());
        if (!Objects.equals(approval.getApplicantId(), StpUtil.getLoginIdAsString())) {
            throw new CommonException("无权限操作");
        }
        approval.setApprovalStatus(BizApprovalEnum.RECALL.getValue());
        this.updateById(approval);
    }

    @Override
    public List<BizApprovalOrderCanteenStatisticsResult> canteenStatisticsList() {
        //当前时间的一个月的时间
        String oneMonthBegin = DateUtil.format(DateUtil.offsetMonth(new java.util.Date(), -1), "yyyy-MM-dd HH:mm:ss");
        String oneMonthEnd = DateUtil.format(DateUtil.offsetMonth(new java.util.Date(), 1), "yyyy-MM-dd HH:mm:ss");
        return this.baseMapper.canteenStatisticsList(oneMonthBegin,
                oneMonthEnd, StpLoginUserUtil.getLoginUser().getCanteenId());
    }


    public List<BizApprovalCanteenUserResult> getBizApprovalCanteenUserResult(String dateStr) {
        DateTime date = DateUtil.parse(dateStr);
        // 转换为字符串输出
        String startStr = DateUtil.format(DateUtil.beginOfDay(date), "yyyy-MM-dd HH:mm:ss");
        String endStr = DateUtil.format(DateUtil.endOfDay(date), "yyyy-MM-dd HH:mm:ss");

        //食堂id
        String canteenId = StpLoginUserUtil.getLoginUser().getCanteenId();
        //查询申请通过的申请指定时间的申请午餐-姓名-部门-手机号-是否就餐
        //午餐
        QueryWrapper<BizApproval> lunchQueryWrapper = new QueryWrapper<>();
        lunchQueryWrapper.lambda().eq(BizApproval::getVisitLunchCafeteriaId, canteenId);
        lunchQueryWrapper.lambda().eq(BizApproval::getApprovalStatus, BizApprovalEnum.WAIT_VISIT.getValue());
        lunchQueryWrapper.lambda().between(BizApproval::getVisitTime, startStr, endStr);
        List<BizApproval> lunchList = this.list(lunchQueryWrapper);
        QueryWrapper<BizApproval> supperQueryWrapper = new QueryWrapper<>();
        supperQueryWrapper.lambda().eq(BizApproval::getVisitSupperCafeteriaId, canteenId);
        supperQueryWrapper.lambda().eq(BizApproval::getApprovalStatus, BizApprovalEnum.WAIT_VISIT.getValue());
        supperQueryWrapper.lambda().between(BizApproval::getVisitTime, startStr, endStr);
        List<BizApproval> supperList = this.list(supperQueryWrapper);
        List<String> lunchIds = lunchList.stream().map(BizApproval::getId).toList();
        List<String> supperIds = supperList.stream().map(BizApproval::getId).toList();
        //查询支付表，是否用餐
        //午餐已支付订单信息
        List<String> lunchOrderIds=new ArrayList<>();
        if (!lunchIds.isEmpty()){
            QueryWrapper<BizApprovalOrder> lunchOrderQueryWrapper = new QueryWrapper<>();
            lunchOrderQueryWrapper.lambda().in(BizApprovalOrder::getApprovalId, lunchIds);
            lunchOrderQueryWrapper.lambda().eq(BizApprovalOrder::getCafeteriaType, BizApprovalCafeteriaTypeEnum.LUNCH.getValue());
            lunchOrderQueryWrapper.lambda().eq(BizApprovalOrder::getPayType, BizApprovalPayTypeEnum.TRUE.getValue());
            List<BizApprovalOrder> lunchOrderList = bizApprovalOrderService.list(lunchOrderQueryWrapper);
            lunchOrderIds.addAll(lunchOrderList.stream().map(BizApprovalOrder::getApprovalId).toList());
        }
        //晚餐已支付订单信息
        List<String> supperOrderIds =new ArrayList<>();
        if (!supperIds.isEmpty()){
            QueryWrapper<BizApprovalOrder> supperOrderQueryWrapper = new QueryWrapper<>();
            supperOrderQueryWrapper.lambda().in(BizApprovalOrder::getApprovalId, supperIds);
            supperOrderQueryWrapper.lambda().eq(BizApprovalOrder::getCafeteriaType, BizApprovalCafeteriaTypeEnum.SUPPER.getValue());
            supperOrderQueryWrapper.lambda().eq(BizApprovalOrder::getPayType, BizApprovalPayTypeEnum.TRUE.getValue());
            List<BizApprovalOrder> supperOrderList = bizApprovalOrderService.list(supperOrderQueryWrapper);
            supperOrderIds.addAll(supperOrderList.stream().map(BizApprovalOrder::getApprovalId).toList());
        }
        ArrayList<BizApprovalCanteenUserResult> results = new ArrayList<>();
        lunchList.forEach(lunch -> {
            BizApprovalCanteenUserResult result = new BizApprovalCanteenUserResult();
            result.setUserName(lunch.getApplicantName());
            result.setType(BizApprovalCafeteriaTypeEnum.LUNCH.getInfo());
            result.setDeptName(lunch.getApplicantDeptName());
            result.setPhone(lunch.getApplicantDeptPhone());
            result.setEat(lunchOrderIds.contains(lunch.getId()));
            results.add(result);
        });
        supperList.forEach(supper -> {
            BizApprovalCanteenUserResult result = new BizApprovalCanteenUserResult();
            result.setUserName(supper.getApplicantName());
            result.setType(BizApprovalCafeteriaTypeEnum.SUPPER.getInfo());
            result.setDeptName(supper.getApplicantDeptName());
            result.setPhone(supper.getApplicantDeptPhone());
            result.setEat(supperOrderIds.contains(supper.getId()));
            results.add(result);
        });
        return results;
    }
}
